package com.biao.java8.demo;

import com.biao.java8.demo.pojo.Employee;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

public class TestStreamAPI2 {
    public static void main(String[] args) {
        // 中间操作
        List<Employee> emps = Arrays.asList(
                new Employee("李四", 59, 6666.66),
                new Employee("张三", 18, 9999.99),
                new Employee("王五", 28, 3333.33),
                new Employee("赵六", 8, 7777.77),
                new Employee("赵六", 8, 7777.77),
                new Employee("赵六", 8, 7777.77),
                new Employee("田七", 38, 5555.55),
                new Employee("田七", 38, 5555.55)
        );
        /*
          筛选与切片
            filter——接收 Lambda ， 从流中排除某些元素。
            limit——截断流，使其元素不超过给定数量。
            skip(n) —— 跳过元素，返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个，则返回一个空流。与 limit(n) 互补
            distinct——筛选，通过流所生成元素的 hashCode() 和 equals() 去除重复元素
         */
        Stream<Employee> stream = emps.stream()
                .filter(e -> e.getAge() < 30)
                .skip(1)     // 跳过第一个小的，也就是age最小的
                .distinct();    // 去重一定要重写hash 和 equals
        stream.forEach(System.out::println);

        System.out.println("-----------------------------");
        /*
            映射
            map 接收lambda,将元素转为其他形式提取信息,接受一个函数作为参数,函数会应用的每个元素,将其映射为一个新的元素
            flatMap 接收一个函数作为参数,把流总的每个值换成另一个流,把所有流连成一个流
         */
        List<String> stringList = Arrays.asList("aaa", "bbb", "ccc", "ddd");
        stringList.stream()
                .map(s -> s.toUpperCase())      // 转大写
                .forEach(System.out::println);
        // 使用flatMap
        stringList.stream()
                .flatMap(TestStreamAPI2::filterCharacter)       // 转成字符数组一个一个输出
                .forEach(System.out::println);

        System.out.println("---------------------------");
        /*
            排序
            sorted()    自然排序Comparable
            sorted(Compatator com)      定制排序Comparator
         */
        stringList.stream()
                .sorted()   // 排序
                .forEach(System.out::println);

        emps.stream()
                .sorted((e1, e2) -> {
                    if (e1.getAge().equals(e2.getAge())) {
                        return e1.getName().compareTo(e2.getName());        // 年龄相等比较名字
                    } else {
                        return e1.getAge().compareTo(e2.getAge());          // 比较年龄
                    }
                }).distinct()       // 去重
                .forEach(System.out::println);

        System.out.println("------------------------");
        /*
            查找 和 匹配
            allMatch    检查是否匹配所有元素
            anyMatch    检查是否至少匹配一个元素
            noneMatch   检查是否没有匹配所有元素
            findFirst   返回第一个元素
            findAny     返回当前流中的任意元素
            count       返回流中元素的总数量
            max         返回流中最大值
            min         返回流中最小值
         */
        // allMatch    检查是否匹配所有元素
        boolean b1 = emps.stream()
                .allMatch(employee -> employee.getName().equals("王五"));     // 是否所以的都叫 王五
        System.out.println("b1: " + b1);
        // anyMatch    检查是否至少匹配一个元素
        boolean b2 = emps.stream()
                .anyMatch(employee -> employee.getName().equals("王五"));     // 是否包含有叫 王五
        System.out.println("b2: " + b2);
        // noneMatch   检查是否没有匹配所有元素
        boolean b3 = emps.stream()
                .noneMatch(employee -> employee.getName().equals("哈哈"));    // 是否没有包含叫 哈哈
        System.out.println("b3: " + b3);
        // findFirst   返回第一个元素
        Optional<Employee> first = emps.stream()
                .sorted((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()))
                .findFirst();   // 根据age 排序后，获取第一个
        System.out.println(first.get());
        // findAny     返回当前流中的任意元素
        Optional<Employee> any = emps.stream()
                .filter(employee -> employee.getAge() == 18)
                .findAny();     // 查找一个满足 age == 18 的，如果有多个，只要其中任意一个
        System.out.println(any.get());
        // count       返回流中元素的总数量
        long count = emps.stream()
                .count();   // 计总
        System.out.println(count);
        // max         返回流中最大值
        Optional<Employee> max = emps.stream()
                .max((e1, e2) -> e1.getAge().compareTo(e2.getAge()));   // 年龄最大的， 若有多个，随机取一个
        System.out.println(max.get());
        // min         返回流中最小值
        Optional<Employee> min = emps.stream()
                .min((e1, e2) -> e1.getAge().compareTo(e2.getAge()));   // 年龄最小的，若有多个，随机取一个
        System.out.println(min.get());

    }

    public static Stream<Character> filterCharacter(String s) {
        ArrayList<Character> list = new ArrayList<>();
        for (Character c : s.toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }
}
